home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 2 / Atari Mega Archive CD - Volume 2.iso / minix / up1510b.tgz / up1510b / src / test / test20.c < prev    next >
C/C++ Source or Header  |  1990-07-23  |  18KB  |  691 lines

  1. /* POSIX test program (20).            Author: Andy Tanenbaum */
  2.  
  3. /* The following POSIX calls are tested:
  4.  *
  5.  *    opendir()
  6.  *    readdir()
  7.  *    rewinddir()
  8.  *    closedir()
  9.  *    chdir()
  10.  *    getcwd()
  11.  */
  12.  
  13.  
  14. #include <sys/types.h>
  15. #include <sys/stat.h>
  16. #include <limits.h>
  17. #include <dirent.h>
  18. #include <fcntl.h>
  19. #include <errno.h>
  20. #include <time.h>
  21. #include <unistd.h>
  22. #include <utime.h>
  23. #include <stdio.h>
  24.  
  25. #define DIR_NULL (DIR*) NULL
  26. #define ITERATIONS         5
  27. #define MAX_FD           100    /* must be large enough to cause error */
  28. #define BUF_SIZE PATH_MAX+20
  29. #define ERR_CODE          -1    /* error return */
  30. #define RD_BUF           200
  31. #define MAX_ERROR          4
  32.  
  33. char str[] = {"The time has come the walrus said to talk of many things.\n"};
  34. char str2[] = {"Of ships and shoes and sealing wax, of cabbages and kings.\n"};
  35. char str3[] = {"Of why the sea is boiling hot and whether pigs have wings\n"};
  36.  
  37. int subtest, errct;
  38. extern errno;
  39.  
  40. main(argc, argv)
  41. int argc;
  42. char *argv[];
  43. {
  44.  
  45.   int i, m=0xFFFF;
  46.  
  47.   sync();
  48.   if (geteuid() == 0) {
  49.     /* Must not run as root. */
  50.     setgid(2);
  51.     setuid(2);
  52.   }
  53.  
  54.   if (argc == 2) m = atoi(argv[1]);
  55.   printf("Test 20 ");
  56.   fflush(stdout);
  57.  
  58.   for (i = 0; i < ITERATIONS; i++) {
  59.     if (m & 00001) test20a();    /* test for correct operation */
  60.     if (m & 00002) test20b();    /* test general error handling */
  61.     if (m & 00004) test20c();    /* test for EMFILE error */
  62.     if (m & 00010) test20d();    /* test chdir() and getcwd() */
  63.     if (m & 00020) test20e();    /* test open() */
  64.     if (m & 00040) test20f();    /* test umask(), stat(), fstat() */
  65.     if (m & 00100) test20g();    /* test link() and unlink() */
  66.     if (m & 00200) test20h();    /* test access() */
  67.     if (m & 00400) test20i();    /* test chmod() and chown() */
  68.     if (m & 01000) test20j();    /* test utime() */
  69.   }
  70.   if (errct == 0)
  71.     printf("ok\n");
  72.   else
  73.     printf(" %d errors\n", errct);
  74.   exit(0);
  75. }
  76.  
  77. test20a()
  78. {
  79. /* Subtest 1. Correct operation */
  80.  
  81.   int f1, f2, f3, f4, f5;
  82.   DIR *dirp;
  83.  
  84.   /* Remove any residue of previous tests. */
  85.   subtest = 1;
  86.  
  87.   system("rm -rf foo");
  88.  
  89.   /* Create a directory foo with 5 files in it. */
  90.   mkdir("foo", 0777);
  91.   if ((f1 = creat("foo/f1", 0666)) < 0) e(1);
  92.   if ((f2 = creat("foo/f2", 0666)) < 0) e(2);
  93.   if ((f3 = creat("foo/f3", 0666)) < 0) e(3);
  94.   if ((f4 = creat("foo/f4", 0666)) < 0) e(4);
  95.   if ((f5 = creat("foo/f5", 0666)) < 0) e(5);
  96.  
  97.   /* Now remove 2 files to create holes in the directory. */
  98.   if (unlink("foo/f2") < 0) e(6);
  99.   if (unlink("foo/f4") < 0) e(7);
  100.  
  101.   /* Close the files. */
  102.   close(f1);
  103.   close(f2);
  104.   close(f3);
  105.   close(f4);
  106.   close(f5);
  107.  
  108.   /* Open the directory. */
  109.   dirp = opendir("./foo");
  110.   if (dirp == DIR_NULL) e(6);
  111.  
  112.   /* Read the 5 files from it. */
  113.   checkdir(dirp, 2); 
  114.  
  115.   /* Rewind dir and test again. */
  116.   rewinddir(dirp);
  117.   checkdir(dirp, 3);
  118.  
  119.   /* We're done.  Close the directory stream. */
  120.   if (closedir(dirp) < 0) e(7);
  121.  
  122.   /* Remove dir for next time. */
  123.   system("rm -rf foo");
  124. }
  125.  
  126. checkdir(dirp, t)
  127. DIR *dirp;            /* poinrter to directory stream */
  128. int t;                /* subtest number to use */
  129. {
  130.  
  131.   int i, f1, f2, f3, f4, f5, dot, dotdot, subt;
  132.   struct dirent *d;
  133.   char *s;
  134.  
  135.   /* Save subtest number */
  136.   subt = subtest;
  137.   subtest = t;
  138.  
  139.   /* Clear the counters. */
  140.   f1 = 0;
  141.   f2 = 0;
  142.   f3 = 0;
  143.   f4 = 0;
  144.   f5 = 0;
  145.   dot = 0;
  146.   dotdot = 0;
  147.  
  148.   /* Read the directory.  It should contain 5 entries, ".", ".." and 3
  149.    * files. */
  150.   for (i = 0; i < 5; i++) {
  151.     d = readdir(dirp);
  152.     if (d == (struct dirent *) NULL) {
  153.         e(1);
  154.         subtest = subt;    /* restore subtest number */
  155.         return;
  156.     }
  157.     s = d->d_name;
  158.     if (strcmp(s, ".") == 0) dot++;
  159.     if (strcmp(s, "..") == 0) dotdot++;
  160.     if (strcmp(s, "f1") == 0) f1++;
  161.     if (strcmp(s, "f2") == 0) f2++;
  162.     if (strcmp(s, "f3") == 0) f3++;
  163.     if (strcmp(s, "f4") == 0) f4++;
  164.     if (strcmp(s, "f5") == 0) f5++;
  165.   }
  166.  
  167.   /* Check results. */
  168.   d = readdir(dirp);
  169.   if (d != (struct dirent *) NULL) e(2);
  170.   if (f1 != 1 || f3 != 1 || f5 != 1) e(3);
  171.   if (f2 != 0 || f4 != 0) e(4);
  172.   if (dot != 1 || dotdot != 1) e(5);
  173.   subtest = subt;
  174.   return;
  175. }
  176.  
  177.  
  178. test20b()
  179. {
  180. /* Subtest 4.  Test error handling. */
  181.  
  182.   int fd, fd2;
  183.   DIR *dirp;
  184.  
  185.   subtest = 4;
  186.  
  187.   if (opendir("foo/xyz/---") != DIR_NULL) e(1);
  188.   if (errno != ENOENT) e(2);
  189.   if (mkdir("foo", 0777) < 0) e(3);
  190.   if (chmod("foo", 0) < 0) e(4);
  191.   if (opendir("foo/xyz/--") != DIR_NULL) e(5);
  192.   if (errno != EACCES) e(6);
  193.   if (chmod("foo", 0777) != 0) e(7);
  194.   if (rmdir("foo") != 0) e(8);
  195.   if ((fd = creat("abc", 0666)) < 0) e(9);
  196.   if (close(fd) < 0) e(10);
  197.   if (opendir("abc/xyz") != DIR_NULL) e(11);
  198.   if (errno != ENOTDIR) e(12);
  199.   if ((dirp = opendir(".")) == DIR_NULL) e(13);
  200.   if (closedir(dirp) != 0) e(14);
  201.   if (closedir(dirp) >= 0) e(15);
  202.   if (readdir(dirp) != (struct dirent *) NULL) e(16);
  203.   if (errno != EBADF) e(17);
  204.   if (readdir(dirp - 2) != (struct dirent *) NULL) e(18);
  205.   if (errno != EBADF) e(19);
  206.   if (unlink("abc") != 0) e(20);
  207.  
  208. }
  209.  
  210.  
  211. test20c()
  212. {
  213. /* Subtest 5.  See what happens if we open too many directory streams. */
  214.  
  215.   int i, j;
  216.   DIR *dirp[MAX_FD];
  217.  
  218.   subtest = 5;
  219.  
  220.   for (i = 0; i < MAX_FD; i++) {
  221.     dirp[i] = opendir(".");
  222.     if (dirp[i] == (DIR *) NULL) {
  223.         /* We have hit the limit. */
  224.         if (errno != EMFILE && errno != ENOMEM) e(1);
  225.         for (j = 0; j < i; j++) {
  226.             if (closedir(dirp[j]) != 0) e(2);    /* close */
  227.         }
  228.         return;
  229.     }
  230.   }
  231.  
  232.   /* Control should never come here.  This is an error. */
  233.   e(3);
  234.   for (i = 0; i < MAX_FD; i++) closedir(dirp[i]);    /* don't check */
  235. }
  236.  
  237. test20d()
  238. {
  239. /* Test chdir and getcwd(). */
  240.  
  241.   int i, fd;
  242.   char *s;
  243.   char base[BUF_SIZE], buf2[BUF_SIZE], tmp[BUF_SIZE];
  244.  
  245.   subtest = 6;
  246.  
  247.   if (getcwd(base, BUF_SIZE) == (char *) NULL)     e(1); /* get test dir's path */
  248.   if (system("rm -rf Dir") != 0) e(2);    /* remove residue of previous test */
  249.   if (mkdir("Dir", 0777) < 0) e(3);     /* create directory called "Dir" */
  250.  
  251.   /* Change to Dir and verify that it worked. */
  252.   if (chdir("Dir") < 0) e(4);    /* go to Dir */
  253.   s = getcwd(buf2, BUF_SIZE);    /* get full path of Dir */
  254.   if (s == (char *) NULL) e(5);    /* check for error return */
  255.   if (s != buf2) e(6);        /* if successful, first arg is returned */
  256.   strcpy(tmp, base);        /* concatenate base name and "/Dir" */
  257.   strcat(tmp, "/");
  258.   strcat(tmp, "Dir");
  259.   if (strcmp(tmp, s) != 0) e(7);
  260.  
  261.   /* Change to ".." and verify that it worked. */
  262.   if (chdir("..") < 0) e(8);
  263.   if (getcwd(buf2, BUF_SIZE) != buf2) e(9);
  264.   if (strcmp(buf2, base) != 0) e(10);
  265.  
  266.   /* Now make calls that do nothing, but do it in a strange way. */
  267.   if (chdir("Dir/..") < 0) e(11);
  268.   if (getcwd(buf2, BUF_SIZE) != buf2) e(12);
  269.   if (strcmp(buf2, base) != 0) e(13);
  270.  
  271.   if (chdir("Dir/../Dir/..") < 0) e(14);
  272.   if (getcwd(buf2, BUF_SIZE) != buf2) e(15);
  273.   if (strcmp(buf2, base) != 0) e(16);
  274.  
  275.   if (chdir("Dir/../Dir/../Dir/../Dir/../Dir/../Dir/../Dir/..") < 0) e(17);
  276.   if (getcwd(buf2, BUF_SIZE) != buf2) e(18);
  277.   if (strcmp(buf2, base) != 0) e(19);
  278.  
  279.   /* Make Dir unreadable and unsearchable.  Check error message. */
  280.   if (chmod("Dir", 0) < 0) e(20);
  281.   if (chdir("Dir") >= 0) e(21);
  282.   if (errno != EACCES) e(22);
  283.  
  284.   /* Check error message for bad path. */
  285.   if (chmod("Dir", 0777) < 0) e(23);
  286.   if (chdir("Dir/x/y") != ERR_CODE) e(24);
  287.   if (errno != ENOENT) e(25);
  288.  
  289.   if ( (fd=creat("Dir/x", 0777)) < 0) e(26);
  290.   if (close(fd) != 0) e(27);
  291.   if (chdir("Dir/x/y") != ERR_CODE) e(28);
  292.   if (errno != ENOTDIR) e(29);  
  293.  
  294.   /* Check empty string. */
  295.   if (chdir("") != ERR_CODE) e(30);
  296.   if (errno != ENOENT) e(31);
  297.  
  298.   /* Remove the directory. */
  299.   if (unlink("Dir/x") != 0) e(32);
  300.   if (system("rmdir Dir") != 0) e(33);
  301. }
  302.  
  303.  
  304. test20e()
  305. {
  306. /* Test open. */
  307.  
  308.   int fd, bytes, bytes2, n;
  309.   char buf[RD_BUF];
  310.  
  311.   subtest = 7;
  312.  
  313.   unlink("T20");        /* get rid of it in case it exists */
  314.  
  315.   /* Create a test file. */
  316.   bytes = strlen(str);
  317.   bytes2 = strlen(str2);
  318.   if ((fd = creat("T20", 0777)) < 0) e(1);
  319.   if (write(fd, str, bytes) != bytes) e(2);    /* T20 now has 'bytes' bytes */
  320.   if (close(fd) != 0) e(3);
  321.  
  322.   /* Test opening a file with O_RDONLY. */
  323.   if ((fd = open("T20", O_RDONLY)) < 0) e(4);
  324.   buf[0] = '\0';
  325.   if (read(fd, buf, RD_BUF) != bytes) e(5);
  326.   if (strncmp(buf, str, bytes) != 0) e(6);
  327.   if (close(fd) < 0) e(7);
  328.  
  329.   /* Test the same thing, only with O_RDWR now. */
  330.   if ((fd = open("T20", O_RDWR)) < 0) e(8);
  331.   buf[0] = '\0';
  332.   if (read(fd,